/*
 * ELight.cpp
 *
 *  Created on: 25-05-2013
 *      Author: Jarek
 */

#include "ELight.h"
#include "EMesh.h"
#include "ECameraLogic.h"

Light::Light() :
	lightType				(LIGHT_TYPE_SPOT),
	position				(Vector4<float>(0.0f, 0.0f, 0.0f, 0.0f)),
	direction				(Vector3<float>(0.0f, 0.0f, 0.0f)),
	ambient					(0.0f, 0.0f, 0.0f, 0.0f),
	diffuse					(0.0f, 0.0f, 0.0f, 0.0f),
	specular				(0.0f, 0.0f, 0.0f, 0.0f),
	zNear					(1.0f),
	zFar					(250.0f),
	constantAttenuation		(0.0f),
	linearAttenuation		(0.0f),
	quadraticAttenuation 	(0.0f),
	spotCutoff				(0.0f),
	spotExponent			(0.0f)
{
	nodeType		= NODE_TYPE_LIGHT;
}

Light::~Light()
{
	// TODO Auto-generated destructor stub
}

void Light::createLight(const aiLight& light)
{
	setName(light.mName.data);

	switch (light.mType)
	{
		case aiLightSource_UNDEFINED:
			LOGI("light is undefined %s", light.mName.data);
			break;
		case aiLightSource_POINT:
			this->lightType				= LIGHT_TYPE_POINT;
			this->position				= Vector4<float>(light.mPosition.x, light.mPosition.y, light.mPosition.z, 1.0f);
			this->spotCutoff			= 2.0 * M_PI;
			break;
		case aiLightSource_SPOT:
			this->lightType				= LIGHT_TYPE_SPOT;
			this->position				= Vector4<float>(light.mPosition.x, light.mPosition.y, light.mPosition.z, 1.0f);
			this->direction				= Vector3<float>(light.mDirection.x, light.mDirection.y, light.mDirection.z);
			this->spotCutoff			= light.mAngleInnerCone / 2.0f;
			this->spotExponent			= 0.0f;
			break;
		case aiLightSource_DIRECTIONAL:
			this->lightType				= LIGHT_TYPE_DIRECTIONAL;
			this->direction				= Vector3<float>(light.mDirection.x, light.mDirection.y, light.mDirection.z);
			break;
	}

	LOGI("found light name: %s type: %d", light.mName.data, this->lightType);

	this->constantAttenuation			= light.mAttenuationConstant;
	this->linearAttenuation				= light.mAttenuationLinear;
	this->quadraticAttenuation			= light.mAttenuationQuadratic;

	if(constantAttenuation == 0.0f && linearAttenuation == 1.0f && quadraticAttenuation == 0.0f)
	{
		constantAttenuation				= 1.0f;
		linearAttenuation				= 0.0f;
	}

	this->ambient						= Vector4<float>(light.mColorAmbient.r, light.mColorAmbient.g, light.mColorAmbient.b, 1.0f);
	this->diffuse						= Vector4<float>(light.mColorDiffuse.r, light.mColorDiffuse.g, light.mColorDiffuse.b, 1.0f);
	this->specular						= Vector4<float>(light.mColorSpecular.r, light.mColorSpecular.g, light.mColorSpecular.b, 1.0f);
}

Matrix4x4<float> Light::getViewMatrix(const ETime& time)
{
	return getWorldMatrix(time).invert();
}

Matrix4x4<float> Light::getModelViewMatrix(const ETime& time, const Matrix4x4<float>& modelMatrix)
{
	return getViewMatrix(time) * modelMatrix;
}

Matrix4x4<float> Light::getModelViewProjectionMatrix(const ETime& time, const Matrix4x4<float>& modelMatrix)
{
	Matrix4x4<float> modelViewMatrix = getModelViewMatrix(time, modelMatrix);

	CameraLogic camera;
	camera.setProjectionMatrix(1.0f, spotCutoff * 2.0f, zNear, zFar);

	return camera.projectionMatrix * modelViewMatrix;
}



